from django.shortcuts import render, get_object_or_404,redirect, reverse
from .models import CourseCategory, Course, Purchase
from django.http import StreamingHttpResponse
import os
import re

# Create your views here.


def index_handler(req):
    categories = []
    for c in CourseCategory.objects.all():
        categories.append({'name': c.name, 'courses': c.course_set.all()})
    return render(req, 'index.html', context={'categories': categories})



def detail_handler(req, cid):
    course = get_object_or_404(Course, pk = cid)
    return render(req, 'course.html',context={'course': course})


def cart_handler(req, cid):
    if  not (req.user.course_set.filter(pk = cid).exists()):
        req.user.course_set.add(get_object_or_404(Course, pk = cid))
    return redirect(reverse('user_cart'))
    

def buy_handler(req, cid):
    course = get_object_or_404(Course, pk = cid)
    if req.user.balance > course.price:
        req.user.balance -= course.price
        req.user.save()
        p = Purchase.objects.filter(user = req.user, course = course).first()
        if not p:
            p = Purchase(user = req.user, course = course)
        if p.state == 'PD':
            return redirect(reverse('course_view', args = [cid]))
        p.state = 'PD'
        p.save()
        return redirect(reverse('course_view', args = [cid]))
    return redirect(reverse('course_detail',args = [cid]))


def view_handler(req,cid):
    if not Purchase.objects.filter(user = req.user, course = cid, state = 'PD'):
        return redirect(reverse('course_detail', args = [cid]))
    
    return render(req,'video.html', context={
        'course':get_object_or_404(Course, pk = cid)
    })



def stream_handler(req, cid):
    if not Purchase.objects.filter(user = req.user, course = cid, state = 'PD'):
        return redirect(reverse('course_detail', args = [cid]))
    def read_video(path, offset, length):
        with open(path, 'rb') as f:
            f.seek(offset)
            while True:
                data = f.read(length)
                if data: yield data
                else: break

    course = get_object_or_404(Course, pk = cid)
    fsize = os.path.getsize(str(course.vedio))
    # 请求头中的range
    request_range = req.headers.get('range')
    # 得到客户端想得到数据的起始位置
    start_bytes = re.findall('=(\d+)-',request_range)
    start_bytes = int(start_bytes[0]) if start_bytes else 0
    # 定义数据终止位置
    last_bytes = start_bytes + 1024 * 1024
    last_bytes = min(last_bytes,fsize-1)
    # 数据长度
    length = last_bytes - start_bytes + 1
    # 构造response对象
    response = StreamingHttpResponse(
        read_video(
            str(course.vedio),
            length=length,
            offset=start_bytes,
        ),
        status=206,
    )
    # 设置响应字节流的长度
    response['Content-Length'] = str(length)
    # Content-Range：bytes 起始字节位-终止字节位/总字节位
    response['Content-Range'] = 'bytes %s-%s/%s' % (start_bytes,last_bytes,fsize)
    return response